﻿using System.Collections;
using System.Collections.Generic;
using System.Xml;


namespace BackEndProcessorInterface
{
    class PostProcessorFiles
    {
        private readonly XmlDocument source;       
        private int depth = -1;
        private readonly List<PConfig> configs;

        public PostProcessorFiles(string filename)
        {
            FileName = filename;
            try
            {
                configs = new List<PConfig>();
                source = new XmlDocument();
            }
            catch (XmlException) { }
        } 
        public PostProcessorFiles()
        {
            FileName = "";
            try
            {
            configs = new List<PConfig>();
            source = new XmlDocument();                   
            }
             catch (XmlException) { }          
        }
        public void Load(string filename)
        {
            if (source == null)
                return;
            try
            {
                source.Load(filename);    
                var reader = new XmlNodeReader(source);
                var configNode = new PConfig();
                var name = "";
                object val = null;

                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            depth++;
                            if (depth == 0)
                                Name = reader.Name;
                            else
                            {
                                if (depth == 1)
                                {
                                    configNode = new PConfig {Name = reader.Name};
                                }
                                else
                                    name = reader.Name;
                            }
                            break;
                        case XmlNodeType.EndElement:
                            if (depth == 1)
                                configs.Add(configNode);
                            else
                                if (depth > 1)
                                    configNode.Add(name, val);
                            depth--;
                            break;
                        case XmlNodeType.Text:
                            if (depth > 1)
                                val = reader.Value;
                            break;
                    }
                }
            }
            catch (XmlException) { }
            
        }
        public bool Save(string filename)
        {
            if (filename == null)
                return false;                                   //filename is null
            try
            {
               
                    using (XmlWriter writer = XmlWriter.Create(filename))
                    {
                        if (writer != null)
                        {
                            writer.WriteStartElement(Name); // <-- Important root element
                            // writer.WriteString("\r\n");
                            foreach (var conf in configs)
                            {
                                Save(conf, writer);
                            }                    
                            // writer.WriteString("\r\n");
                            writer.WriteEndElement();              // <-- Closes it 
                        }
                        else
                            return false; //Can't create writer
                    
                    }
            }
            catch (XmlException) {
                return false; }             //!
            return true;                   //it's norm
        }
        public void Save(PConfig pconfig)
        {
            try
            {
                using (var writer = XmlWriter.Create(FileName))
                {
                    Save(pconfig, writer);                
                }
            }
            catch (XmlException) { }
        }
        public void Save(PConfig config, XmlWriter writer)
        {
            writer.WriteStartElement(config.Name); // <-- Important root element
            //writer.WriteString("\r\n");
            var inum = config.GetEnumerator();
            while (inum.MoveNext())
            {
                var dictionary = (DictionaryEntry)inum.Current;
                writer.WriteStartElement(dictionary.Key.ToString());
                writer.WriteValue(config.asBool(dictionary.Key, false));
                writer.WriteEndElement();
                //writer.WriteString("\r\n");

            }
           // writer.WriteString("\r\n");
            writer.WriteEndElement();              // <-- Closes it  
        }
        public PConfig GetConfig(string name)
        {
            return SeachConfig(name); 
        }

        public string Name { get; set; }

        public string FileName { get; set; }

        public PConfig SeachConfig(string name)
        {
            var ienum = configs.GetEnumerator();
            while (ienum.MoveNext())
            {
                var current = ienum.Current;
                if(name.Equals(current.Name))
                    return current;
            }
            return null;
        }
        public  int SeachConfigIndex(string name)
        {
            for(int i = 0; i < configs.Count; i++)
            {
                if(name.Equals(configs[i].Name))
                    return i;
            }
            return -1;
        }
        public  void Clear()
        {
            configs.Clear();
        }
        public  int Add(PConfig conf)
        {
            if (configs == null) return  1;
            var iS = SeachConfigIndex(conf.Name);
            if(iS > -1)
            {
                configs.RemoveAt(iS);
                configs.Insert(iS,conf);
            }
            else
                configs.Add(conf);
            return 0;
        }
    }
}
